<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 9 Linking Widgets | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 9 Linking Widgets | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 9 Linking Widgets | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-08-24" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="advanced-topics.html"/>
<link rel="next" href="final-revisions.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="overview.html"><a href="overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a>
<ul>
<li class="chapter" data-level="1.1" data-path="overview.html"><a href="overview.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="overview.html"><a href="overview.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="overview.html"><a href="overview.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="overview.html"><a href="overview.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="overview.html"><a href="overview.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="overview.html"><a href="overview.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="overview.html"><a href="overview.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of building widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly"><i class="fa fa-check"></i><b>4.1.1</b> Plotly</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-output"><i class="fa fa-check"></i><b>5.2</b> The Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#javascript-side"><i class="fa fa-check"></i><b>5.3</b> JavaScript-side</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>6.1</b> Dependency</a></li>
<li class="chapter" data-level="6.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>6.2</b> JavaScript</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#in-javascript"><i class="fa fa-check"></i><b>7.4.1</b> In JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#in-r"><i class="fa fa-check"></i><b>7.4.2</b> In R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print"><i class="fa fa-check"></i><b>7.5</b> On Print</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="crosstalk.html"><a href="crosstalk.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a>
<ul>
<li class="chapter" data-level="9.1" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk examples</a></li>
<li class="chapter" data-level="9.2" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="crosstalk.html"><a href="crosstalk.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="crosstalk.html"><a href="crosstalk.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="crosstalk.html"><a href="crosstalk.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="crosstalk.html"><a href="crosstalk.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="crosstalk.html"><a href="crosstalk.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.6.3</b> Using crosstalk with gio</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>10.1</b> Working with data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover-plotly"><i class="fa fa-check"></i><b>11.1</b> Discover Plotly</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics-of-plotly"><i class="fa fa-check"></i><b>11.2</b> Basics of plotly</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>11.3</b> JavaScript to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>11.4</b> R to JavaScript</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html"><i class="fa fa-check"></i><b>12</b> Introduction to shiny</a>
<ul>
<li class="chapter" data-level="12.1" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#websocket"><i class="fa fa-check"></i><b>12.1</b> Websocket</a></li>
<li class="chapter" data-level="12.2" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#static-files"><i class="fa fa-check"></i><b>12.2</b> Static files</a></li>
<li class="chapter" data-level="12.3" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#walkthrough---alerts"><i class="fa fa-check"></i><b>12.3</b> Walkthrough - Alerts</a></li>
<li class="chapter" data-level="12.4" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#from-r-to-javascript"><i class="fa fa-check"></i><b>12.4</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.5" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#from-javascript-to-r"><i class="fa fa-check"></i><b>12.5</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.6" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#deserialise"><i class="fa fa-check"></i><b>12.6</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom outputs inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>15.2</b> Setup</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#r-function"><i class="fa fa-check"></i><b>15.3</b> R function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#output"><i class="fa fa-check"></i><b>15.4</b> Output</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#render"><i class="fa fa-check"></i><b>15.5</b> Render</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript output binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#background-color"><i class="fa fa-check"></i><b>15.7</b> Background color</a>
<ul>
<li class="chapter" data-level="15.7.1" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-output-binding"><i class="fa fa-check"></i><b>15.7.1</b> Register the output binding</a></li>
</ul></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.8</b> Boxxy usage</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a>
<ul>
<li class="chapter" data-level="16.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>16.2</b> Setup</a></li>
<li class="chapter" data-level="16.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript</a></li>
<li class="chapter" data-level="16.4" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="17.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>17.1</b> JavaScript to R</a></li>
<li class="chapter" data-level="17.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#input-handlers-for-widgets"><i class="fa fa-check"></i><b>17.2</b> Input handlers for widgets</a></li>
<li class="chapter" data-level="17.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>17.3</b> R to JavaScript</a>
<ul>
<li class="chapter" data-level="17.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data</a></li>
<li class="chapter" data-level="17.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update"><i class="fa fa-check"></i><b>17.6</b> Update</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="18.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>18.4</b> With Npm</a></li>
<li class="chapter" data-level="18.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html"><i class="fa fa-check"></i><b>19</b> Exercise - Machine Learning</a>
<ul>
<li class="chapter" data-level="19.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>19.1</b> Dependency</a></li>
<li class="chapter" data-level="19.2" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>19.2</b> Simple Regression</a></li>
</ul></li>
<li class="part"><span><b>V Examples</b></span></li>
<li class="chapter" data-level="20" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>20</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="20.1" data-path="image-classifier.html"><a href="image-classifier.html#discover"><i class="fa fa-check"></i><b>20.1</b> Discover</a></li>
<li class="chapter" data-level="20.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>20.2</b> Setup</a></li>
<li class="chapter" data-level="20.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>20.3</b> JavaScript</a></li>
<li class="chapter" data-level="20.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>20.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>21</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="21.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>21.1</b> R code</a></li>
<li class="chapter" data-level="21.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>21.2</b> JavaScript code</a></li>
<li class="chapter" data-level="21.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>21.3</b> Events</a></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="22" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>22</b> Conclusion</a>
<ul>
<li class="chapter" data-level="22.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>22.1</b> Performances</a></li>
<li class="chapter" data-level="22.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>22.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="22.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>22.2.1</b> Computation</a></li>
<li class="chapter" data-level="22.2.2" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>22.2.2</b> Shiny</a></li>
<li class="chapter" data-level="22.2.3" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>22.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="crosstalk" class="section level1" number="9">
<h1><span class="header-section-number">Chapter 9</span> Linking Widgets</h1>
<p>Widgets can be linked with one another using the crosstalk <span class="citation">(Cheng <a href="#ref-R-crosstalk" role="doc-biblioref">2020</a>)</span> package, a fantastic add-on for htmlwidgets that implements cross-widget interactions, namely selection and filtering. This in effect allows the selection or filtering of data points in one widget to be mirrored in another. This is enabled by the creation of “shared datasets” that can be used across widgets.</p>
<p>Crosstalk provides a straightforward interface to the users and instead requires effort from the developers for their widgets to support the shared datasets.</p>
<div id="crosstalk-examples" class="section level2" number="9.1">
<h2><span class="header-section-number">9.1</span> Crosstalk examples</h2>
<p>Both the plotly and DT packages support crosstalk, we can thus produce a scatter plot with the former and a table with the latter so that selection of data in one is reflected in the other.</p>
<p>The shared dataset is created with the <code>SharedData</code> R6 class from the crosstalk package, this dataset is then used as one would use a standard dataframe in plotly and DT. The <code>bscols</code> function is just a helper to create columns from html elements (using bootstrap). It’s ideal for examples but one should not have to use it in Shiny—crosstalk will work without <code>bscols</code>.</p>
<div class="sourceCode" id="cb171"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb171-1"><a href="crosstalk.html#cb171-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb171-2"><a href="crosstalk.html#cb171-2"></a><span class="kw">library</span>(plotly)</span>
<span id="cb171-3"><a href="crosstalk.html#cb171-3"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb171-4"><a href="crosstalk.html#cb171-4"></a></span>
<span id="cb171-5"><a href="crosstalk.html#cb171-5"></a>shared &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(cars)</span>
<span id="cb171-6"><a href="crosstalk.html#cb171-6"></a></span>
<span id="cb171-7"><a href="crosstalk.html#cb171-7"></a><span class="kw">bscols</span>(</span>
<span id="cb171-8"><a href="crosstalk.html#cb171-8"></a>  <span class="kw">plot_ly</span>(shared, <span class="dt">x =</span> <span class="op">~</span>speed, <span class="dt">y=</span><span class="op">~</span>dist),</span>
<span id="cb171-9"><a href="crosstalk.html#cb171-9"></a>  <span class="kw">datatable</span>(shared, <span class="dt">width =</span> <span class="st">&quot;100%&quot;</span>)</span>
<span id="cb171-10"><a href="crosstalk.html#cb171-10"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/crosstalk.png" alt="" />
<p class="caption">Crosstalk Example</p>
</div>
<p>Basic usage of crosstalk datasets in shiny is very straightforward since it accepts reactive expressions to create shared datasets. Note that it takes the expression itself (<code>reactive</code>) not the output of the expression (<code>expression()</code>), the crosstalk documentation explains it best:</p>
<blockquote>
<p>If this feels foreign to you, think of how you pass a function name, not a function call, to <code>lapply</code>; that’s exactly analogous to what we’re doing here.</p>
<p>— Official Crosstalk documentation</p>
</blockquote>
<div class="sourceCode" id="cb172"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb172-1"><a href="crosstalk.html#cb172-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb172-2"><a href="crosstalk.html#cb172-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb172-3"><a href="crosstalk.html#cb172-3"></a><span class="kw">library</span>(plotly)</span>
<span id="cb172-4"><a href="crosstalk.html#cb172-4"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb172-5"><a href="crosstalk.html#cb172-5"></a></span>
<span id="cb172-6"><a href="crosstalk.html#cb172-6"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb172-7"><a href="crosstalk.html#cb172-7"></a>  <span class="kw">selectInput</span>(</span>
<span id="cb172-8"><a href="crosstalk.html#cb172-8"></a>    <span class="st">&quot;specie&quot;</span>, <span class="st">&quot;Specie&quot;</span>, </span>
<span id="cb172-9"><a href="crosstalk.html#cb172-9"></a>    <span class="dt">choices =</span> <span class="kw">c</span>(<span class="st">&quot;setosa&quot;</span>, <span class="st">&quot;versicolor&quot;</span>, <span class="st">&quot;virginica&quot;</span>)</span>
<span id="cb172-10"><a href="crosstalk.html#cb172-10"></a>  ),</span>
<span id="cb172-11"><a href="crosstalk.html#cb172-11"></a>  <span class="kw">fluidRow</span>(</span>
<span id="cb172-12"><a href="crosstalk.html#cb172-12"></a>    <span class="kw">column</span>(<span class="dv">6</span>, <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>)),</span>
<span id="cb172-13"><a href="crosstalk.html#cb172-13"></a>    <span class="kw">column</span>(<span class="dv">6</span>, <span class="kw">plotlyOutput</span>(<span class="st">&quot;plot&quot;</span>))</span>
<span id="cb172-14"><a href="crosstalk.html#cb172-14"></a>  )</span>
<span id="cb172-15"><a href="crosstalk.html#cb172-15"></a>)</span>
<span id="cb172-16"><a href="crosstalk.html#cb172-16"></a></span>
<span id="cb172-17"><a href="crosstalk.html#cb172-17"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb172-18"><a href="crosstalk.html#cb172-18"></a>  reactive_data &lt;-<span class="st"> </span><span class="kw">reactive</span>({</span>
<span id="cb172-19"><a href="crosstalk.html#cb172-19"></a>    iris[iris<span class="op">$</span>Species <span class="op">==</span><span class="st"> </span>input<span class="op">$</span>specie, ]</span>
<span id="cb172-20"><a href="crosstalk.html#cb172-20"></a>  })</span>
<span id="cb172-21"><a href="crosstalk.html#cb172-21"></a></span>
<span id="cb172-22"><a href="crosstalk.html#cb172-22"></a>  sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(reactive_data)</span>
<span id="cb172-23"><a href="crosstalk.html#cb172-23"></a></span>
<span id="cb172-24"><a href="crosstalk.html#cb172-24"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb172-25"><a href="crosstalk.html#cb172-25"></a>    <span class="kw">datatable</span>(sd)</span>
<span id="cb172-26"><a href="crosstalk.html#cb172-26"></a>  }, <span class="dt">server =</span> <span class="ot">FALSE</span>)</span>
<span id="cb172-27"><a href="crosstalk.html#cb172-27"></a></span>
<span id="cb172-28"><a href="crosstalk.html#cb172-28"></a>  output<span class="op">$</span>plot &lt;-<span class="st"> </span><span class="kw">renderPlotly</span>({</span>
<span id="cb172-29"><a href="crosstalk.html#cb172-29"></a>    <span class="kw">plot_ly</span>(sd, <span class="dt">x =</span> <span class="op">~</span>Sepal.Length, <span class="dt">y =</span> <span class="op">~</span>Sepal.Width)</span>
<span id="cb172-30"><a href="crosstalk.html#cb172-30"></a>  })</span>
<span id="cb172-31"><a href="crosstalk.html#cb172-31"></a>}</span>
<span id="cb172-32"><a href="crosstalk.html#cb172-32"></a></span>
<span id="cb172-33"><a href="crosstalk.html#cb172-33"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="rmdnote">
<p>
Create the shared dataset in the server function or some things might not work as expected in shiny.
</p>
</div>
<p>One can also use the <code>data</code> method on the crosstalk object in reactive expressions, which allows accessing the Javascript selection where crosstalk is not directly supported, like below in a custom UI block. Note that the argument <code>withSelection</code> is set to <code>TRUE</code> in order to retrieve the selection state of the rows.</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb173-1"><a href="crosstalk.html#cb173-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb173-2"><a href="crosstalk.html#cb173-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb173-3"><a href="crosstalk.html#cb173-3"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb173-4"><a href="crosstalk.html#cb173-4"></a></span>
<span id="cb173-5"><a href="crosstalk.html#cb173-5"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb173-6"><a href="crosstalk.html#cb173-6"></a>  <span class="kw">fluidRow</span>(</span>
<span id="cb173-7"><a href="crosstalk.html#cb173-7"></a>    <span class="kw">column</span>(<span class="dv">4</span>, <span class="kw">uiOutput</span>(<span class="st">&quot;text&quot;</span>)),</span>
<span id="cb173-8"><a href="crosstalk.html#cb173-8"></a>    <span class="kw">column</span>(<span class="dv">8</span>, <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>))</span>
<span id="cb173-9"><a href="crosstalk.html#cb173-9"></a>  )</span>
<span id="cb173-10"><a href="crosstalk.html#cb173-10"></a>)</span>
<span id="cb173-11"><a href="crosstalk.html#cb173-11"></a></span>
<span id="cb173-12"><a href="crosstalk.html#cb173-12"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb173-13"><a href="crosstalk.html#cb173-13"></a>  sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(cars)</span>
<span id="cb173-14"><a href="crosstalk.html#cb173-14"></a></span>
<span id="cb173-15"><a href="crosstalk.html#cb173-15"></a>  output<span class="op">$</span>text &lt;-<span class="st"> </span><span class="kw">renderUI</span>({</span>
<span id="cb173-16"><a href="crosstalk.html#cb173-16"></a>    <span class="co"># get selected rows</span></span>
<span id="cb173-17"><a href="crosstalk.html#cb173-17"></a>    n_selected &lt;-<span class="st"> </span>sd<span class="op">$</span><span class="kw">data</span>(<span class="dt">withSelection =</span> <span class="ot">TRUE</span>) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb173-18"><a href="crosstalk.html#cb173-18"></a><span class="st">      </span>dplyr<span class="op">::</span><span class="kw">filter</span>(selected_ <span class="op">==</span><span class="st"> </span><span class="ot">TRUE</span>) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb173-19"><a href="crosstalk.html#cb173-19"></a><span class="st">      </span><span class="kw">nrow</span>()</span>
<span id="cb173-20"><a href="crosstalk.html#cb173-20"></a></span>
<span id="cb173-21"><a href="crosstalk.html#cb173-21"></a>    <span class="kw">h3</span>(n_selected, <span class="st">&quot;selected items&quot;</span>)</span>
<span id="cb173-22"><a href="crosstalk.html#cb173-22"></a>    </span>
<span id="cb173-23"><a href="crosstalk.html#cb173-23"></a>  })</span>
<span id="cb173-24"><a href="crosstalk.html#cb173-24"></a></span>
<span id="cb173-25"><a href="crosstalk.html#cb173-25"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb173-26"><a href="crosstalk.html#cb173-26"></a>    <span class="kw">datatable</span>(sd)</span>
<span id="cb173-27"><a href="crosstalk.html#cb173-27"></a>  }, <span class="dt">server =</span> <span class="ot">FALSE</span>)</span>
<span id="cb173-28"><a href="crosstalk.html#cb173-28"></a>}</span>
<span id="cb173-29"><a href="crosstalk.html#cb173-29"></a></span>
<span id="cb173-30"><a href="crosstalk.html#cb173-30"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/crosstalk-shiny.png" alt="" />
<p class="caption">Shiny with crosstalk</p>
</div>
<p>Using crosstalk with shiny one can also change the selection server-side with the <code>selection</code> method, passing it the keys to select.</p>
<div class="sourceCode" id="cb174"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb174-1"><a href="crosstalk.html#cb174-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb174-2"><a href="crosstalk.html#cb174-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb174-3"><a href="crosstalk.html#cb174-3"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb174-4"><a href="crosstalk.html#cb174-4"></a></span>
<span id="cb174-5"><a href="crosstalk.html#cb174-5"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb174-6"><a href="crosstalk.html#cb174-6"></a>  <span class="kw">fluidRow</span>(</span>
<span id="cb174-7"><a href="crosstalk.html#cb174-7"></a>    <span class="kw">column</span>(<span class="dv">4</span>, <span class="kw">actionButton</span>(<span class="st">&quot;random&quot;</span>, <span class="st">&quot;Select a random row&quot;</span>)),</span>
<span id="cb174-8"><a href="crosstalk.html#cb174-8"></a>    <span class="kw">column</span>(<span class="dv">8</span>, <span class="kw">DTOutput</span>(<span class="st">&quot;table&quot;</span>))</span>
<span id="cb174-9"><a href="crosstalk.html#cb174-9"></a>  )</span>
<span id="cb174-10"><a href="crosstalk.html#cb174-10"></a>)</span>
<span id="cb174-11"><a href="crosstalk.html#cb174-11"></a></span>
<span id="cb174-12"><a href="crosstalk.html#cb174-12"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output) {</span>
<span id="cb174-13"><a href="crosstalk.html#cb174-13"></a>  sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(cars)</span>
<span id="cb174-14"><a href="crosstalk.html#cb174-14"></a></span>
<span id="cb174-15"><a href="crosstalk.html#cb174-15"></a>  output<span class="op">$</span>table &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb174-16"><a href="crosstalk.html#cb174-16"></a>    <span class="kw">datatable</span>(sd)</span>
<span id="cb174-17"><a href="crosstalk.html#cb174-17"></a>  }, <span class="dt">server =</span> <span class="ot">FALSE</span>)</span>
<span id="cb174-18"><a href="crosstalk.html#cb174-18"></a></span>
<span id="cb174-19"><a href="crosstalk.html#cb174-19"></a>  selected &lt;-<span class="st"> </span><span class="kw">c</span>()</span>
<span id="cb174-20"><a href="crosstalk.html#cb174-20"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>random, {</span>
<span id="cb174-21"><a href="crosstalk.html#cb174-21"></a>    smp &lt;-<span class="st"> </span><span class="kw">c</span>(<span class="dv">1</span><span class="op">:</span><span class="dv">50</span>)[<span class="op">!</span><span class="dv">1</span><span class="op">:</span><span class="dv">50</span> <span class="op">%in%</span><span class="st"> </span>selected]</span>
<span id="cb174-22"><a href="crosstalk.html#cb174-22"></a>    selected &lt;&lt;-<span class="st"> </span><span class="kw">append</span>(selected, <span class="kw">sample</span>(smp, <span class="dv">1</span>))</span>
<span id="cb174-23"><a href="crosstalk.html#cb174-23"></a>    sd<span class="op">$</span><span class="kw">selection</span>(selected)</span>
<span id="cb174-24"><a href="crosstalk.html#cb174-24"></a>  })</span>
<span id="cb174-25"><a href="crosstalk.html#cb174-25"></a>}</span>
<span id="cb174-26"><a href="crosstalk.html#cb174-26"></a></span>
<span id="cb174-27"><a href="crosstalk.html#cb174-27"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
</div>
<div id="crosstalk-requirements" class="section level2" number="9.2">
<h2><span class="header-section-number">9.2</span> Crosstalk requirements</h2>
<p>Crosstalk is will not work well with every widget and every dataset, in some cases it might not even be a good idea to support it.</p>
<p>Crosstalk works best on rectangular data: dataframes or objects that resemble dataframes like <code>tibble</code> or <code>SpatialPolygonsDataFrame</code>. This is important as crosstalk will treat the data rowwise, where each row is an observation that is ultimately selected, or filtered. If the underlying data is not tabular (e.g.: trees) then one might eventually encounter mismatches between widgets.</p>
<p>Other than tabular data, crosstalk will require the widget to have the necessary functions or methods to dispatch the selection and filtering that crosstalk enables, that is, the widget must be able to filter as well as highlight and fade selected data points.</p>
</div>
<div id="how-it-works" class="section level2" number="9.3">
<h2><span class="header-section-number">9.3</span> How it works</h2>
<p>As will be discovered later when support for crosstalk is brought to gio, very little changes on the R side. As might be expected, crosstalk enables communication between widgets via JavaScript, hence much of what must be adapted by widgets developers happens in JavaScript too.</p>
<div id="htmlwidget-7d709e7d3c6d422b0293" style="width:100%;height:250px;" class="grViz html-widget"></div>
<script type="application/json" data-for="htmlwidget-7d709e7d3c6d422b0293">{"x":{"diagram":"\ndigraph G {\n\n  graph [compound=true rankdir = LR]\n  node [shape=record fontsize=10];\n\n  # r stuff\n  subgraph cluster_1 { \n    \"Widget 1\" \"Widget 2\";\n    label = \"JavaScript\";\n    color=gold;\n  }\n\n  # js\n  subgraph cluster_0 {\n    node [width = 0.9]\n    Dataframe \"Shared Dataset\"; \n    label=\"R\";\n    color=royalBlue;\n  }\n\n  \"Dataframe\" -> \"Shared Dataset\";\n  \"Widget 1\" -> \"Widget 2\" [dir=both color=dimGray];\n\n  # connect subgraphs\n  \"Shared Dataset\" -> \"Widget 1\" [lhead=cluster_1 ltail=cluster_0];\n}\n","config":{"engine":"dot","options":null}},"evals":[],"jsHooks":[]}</script>
<p>Indeed the bi-directional communication between widgets works in the RStudio viewer, R markdown, Shiny and elsewhere, clearly indicating that all of it is taking place in the browser. This internally works with <code>key</code>s that are assigned to every row of the dataframe. These keys can be explicitly set by the user and otherwise default to the row names of the data.frame, and if these are not available the <code>SharedData</code> function will create row numbers.</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb175-1"><a href="crosstalk.html#cb175-1"></a><span class="co"># assign keys</span></span>
<span id="cb175-2"><a href="crosstalk.html#cb175-2"></a>df &lt;-<span class="st"> </span><span class="kw">data.frame</span>(<span class="dt">x =</span> <span class="kw">runif</span>(<span class="dv">26</span>))</span>
<span id="cb175-3"><a href="crosstalk.html#cb175-3"></a>sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(df, <span class="dt">key =</span> letters)</span></code></pre></div>
<p>In a sense, while crosstalk establishes lines of communication to transport <code>key</code>s between widgets, developers of the respective widgets must handle what <code>key</code>s are sent and what to do with incoming <code>key</code>s. There are two types of such messages: filtering to actually narrow down the selection of data points displayed on a widget, and selection (what crosstalk refers to as “linked brushing”) to highlight certain data points.</p>
<div id="htmlwidget-e5f15e3dc90d1c7954bd" style="width:100%;height:250px;" class="grViz html-widget"></div>
<script type="application/json" data-for="htmlwidget-e5f15e3dc90d1c7954bd">{"x":{"diagram":"\ndigraph G {\n\n  subgraph cluster_g1 {\n    node [shape=record fontsize=7]\n    d1 [label=\"Dataset\"]\n    d3 [label=\"Dataset\"]\n    k1 [label=\"Keys\"]\n    label=\"Group 1\"\n    fontsize=9\n    color=royalBlue\n  }\n\n  subgraph cluster_g2 {\n    node [shape=record fontsize=7]\n    d2 [label=\"Dataset\"] \n    k2 [label=\"Keys\"]\n    label=\"Group 2\"\n    fontsize=9\n    color=royalBlue\n  }\n\n  node [shape=record fontsize=7 color=gold]\n  w1 [label=\"widget 1\"]\n  w2 [label=\"widget 2\"]\n  w3 [label=\"widget 3\"]\n  w4 [label=\"widget 4\"]\n  w5 [label=\"widget 5\"]\n\n  w1 -> k1 [dir=both arrowsize=.5]\n  w2 -> k1 [dir=both arrowsize=.5]\n  w3 -> k2 [dir=both arrowsize=.5]\n  w4 -> k2 [dir=both arrowsize=.5]\n  w5 -> k2 [dir=both arrowsize=.5]\n\n  d2 -> k2 [arrowsize=.5]\n  d1 -> k1 [arrowsize=.5]\n  d3 -> k1 [arrowsize=.5]\n\n}\n","config":{"engine":"dot","options":null}},"evals":[],"jsHooks":[]}</script>
<p>In JavaScript, a widget “receives” the keys of selected and filtered data points and must, when filtering or selection is observed, “send” said selected or filtered keys to other widgets. Internally crosstalk knows what to share across widgets with the aforementioned <code>group</code>, groups share <code>key</code>s and are isolated from each other so one can use multiple different shared datasets without them interfering with each other. Therefore, the code below creates two shared datasets created below are linked and share keys despite the fact that they are separate R objects.</p>
<div class="sourceCode" id="cb176"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb176-1"><a href="crosstalk.html#cb176-1"></a>shared_cars &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(mtcars, <span class="dt">group =</span> <span class="st">&quot;cars&quot;</span>)</span>
<span id="cb176-2"><a href="crosstalk.html#cb176-2"></a>shared_cars_head &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(<span class="kw">head</span>(mtcars), <span class="dt">group =</span> <span class="st">&quot;cars&quot;</span>)</span></code></pre></div>
</div>
<div id="crosstalk-with-gio" class="section level2" number="9.4">
<h2><span class="header-section-number">9.4</span> Crosstalk with gio</h2>
<p>The application of crosstalk to the gio library is somewhat amiss. As mentioned or hinted at before, in order for crosstalk to be properly implemented a widget must be a able to select, deselect as well as filter and unfilter data points and this is not entirely the case of gio.</p>
<div class="rmdnote">
<p>
The application of crosstalk to the gio package is instructive but limited and somewhat faulty.
</p>
</div>
<p>First, gio’s underlying data is somewhat uncommon: it is a network defined only by its edges (the arcs leaving and coming into countries). Second, those edges themselves cannot be selected, as we’ve observed previously one cannot truly change what edges are drawn on the globe, only change which country is selected and by proxy which edges are shown. Third, while gio supports changing which country is selected it does not allow having not countries selected.</p>
<p>The way crosstalk can work with gio is by setting the keys of the shared dataset to the country ISO codes that gio uses. Since data gio accepts consists of edges this ISO code could correspond to either source or the target country.</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb177-1"><a href="crosstalk.html#cb177-1"></a>shared_arcs &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(arcs, <span class="dt">key =</span> arcs<span class="op">$</span>i)</span></code></pre></div>
</div>
<div id="adapt-the-r-code" class="section level2" number="9.5">
<h2><span class="header-section-number">9.5</span> Adapt the R code</h2>
<p>In any event, let us start by making the required changes to the R code first. The only changes that need to be made are in the <code>gio</code> function as it is the only that accepts a data object.</p>
<div class="sourceCode" id="cb178"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb178-1"><a href="crosstalk.html#cb178-1"></a><span class="kw">class</span>(shared_arcs)</span></code></pre></div>
<pre><code>## [1] &quot;SharedData&quot; &quot;R6&quot;</code></pre>
<p>The shared datasets are R6 classes and therefore cannot simply be treated as dataframes. The <code>gio</code> function needs to check whether the <code>data</code> object it received is a shared dataset with <code>is.SharedData</code> and if so use its methods to extract data from it, namely:</p>
<ul>
<li>The original dataset with <code>origData</code>.</li>
<li>The group to which the dataset belongs with <code>groupName</code>.</li>
<li>The keys that were assigned to every row of the dataset with <code>key</code></li>
</ul>
<div class="sourceCode" id="cb180"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb180-1"><a href="crosstalk.html#cb180-1"></a><span class="co"># original data</span></span>
<span id="cb180-2"><a href="crosstalk.html#cb180-2"></a>shared_arcs<span class="op">$</span><span class="kw">origData</span>()</span></code></pre></div>
<pre><code>##    e  i       v
## 1 CN US 3300000
## 2 CN RU   10000</code></pre>
<p>Note that the name of the group was randomly generated since none were specified when the shared dataset was created.</p>
<div class="sourceCode" id="cb182"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb182-1"><a href="crosstalk.html#cb182-1"></a><span class="co"># groupName</span></span>
<span id="cb182-2"><a href="crosstalk.html#cb182-2"></a>shared_arcs<span class="op">$</span><span class="kw">groupName</span>()</span></code></pre></div>
<pre><code>## [1] &quot;SharedData5156bc96&quot;</code></pre>
<div class="sourceCode" id="cb184"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb184-1"><a href="crosstalk.html#cb184-1"></a><span class="co"># keys</span></span>
<span id="cb184-2"><a href="crosstalk.html#cb184-2"></a>shared_arcs<span class="op">$</span><span class="kw">key</span>()</span></code></pre></div>
<pre><code>## [1] &quot;US&quot; &quot;RU&quot;</code></pre>
<p>The methods <code>origData</code> and <code>groupName</code> must be used in every widget, the original dataframe is still needed to produce the visualisation and the group will be needed JavaScript so we can tell crosstalk which group one is working with. The <code>key</code> method may not be useful with every widget if the visualisation library also comes with a key/id system so one can use it internally, we won’t be using it with gio. Finally notice that we also add the JavaScript dependency with <code>crosstalkLibs</code>.</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb186-1"><a href="crosstalk.html#cb186-1"></a>gio &lt;-<span class="st"> </span><span class="cf">function</span>(data, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, </span>
<span id="cb186-2"><a href="crosstalk.html#cb186-2"></a>  <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb186-3"><a href="crosstalk.html#cb186-3"></a></span>
<span id="cb186-4"><a href="crosstalk.html#cb186-4"></a>  <span class="co"># defaults to NULL</span></span>
<span id="cb186-5"><a href="crosstalk.html#cb186-5"></a>  group &lt;-<span class="st"> </span><span class="ot">NULL</span></span>
<span id="cb186-6"><a href="crosstalk.html#cb186-6"></a></span>
<span id="cb186-7"><a href="crosstalk.html#cb186-7"></a>  <span class="co"># uses crosstalk</span></span>
<span id="cb186-8"><a href="crosstalk.html#cb186-8"></a>  <span class="cf">if</span> (crosstalk<span class="op">::</span><span class="kw">is.SharedData</span>(data)) {</span>
<span id="cb186-9"><a href="crosstalk.html#cb186-9"></a>    group &lt;-<span class="st"> </span>data<span class="op">$</span><span class="kw">groupName</span>()</span>
<span id="cb186-10"><a href="crosstalk.html#cb186-10"></a>    data &lt;-<span class="st"> </span>data<span class="op">$</span><span class="kw">origData</span>()</span>
<span id="cb186-11"><a href="crosstalk.html#cb186-11"></a>  }</span>
<span id="cb186-12"><a href="crosstalk.html#cb186-12"></a></span>
<span id="cb186-13"><a href="crosstalk.html#cb186-13"></a>  <span class="co"># forward options using x</span></span>
<span id="cb186-14"><a href="crosstalk.html#cb186-14"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb186-15"><a href="crosstalk.html#cb186-15"></a>    <span class="dt">data =</span> data,</span>
<span id="cb186-16"><a href="crosstalk.html#cb186-16"></a>    <span class="dt">style =</span> <span class="st">&quot;default&quot;</span>,</span>
<span id="cb186-17"><a href="crosstalk.html#cb186-17"></a>    <span class="dt">crosstalk =</span> <span class="kw">list</span>(<span class="dt">group =</span> group) <span class="co"># pass group</span></span>
<span id="cb186-18"><a href="crosstalk.html#cb186-18"></a>  )</span>
<span id="cb186-19"><a href="crosstalk.html#cb186-19"></a></span>
<span id="cb186-20"><a href="crosstalk.html#cb186-20"></a>  <span class="kw">attr</span>(x, <span class="st">&#39;TOJSON_ARGS&#39;</span>) &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">dataframe =</span> <span class="st">&quot;rows&quot;</span>)</span>
<span id="cb186-21"><a href="crosstalk.html#cb186-21"></a></span>
<span id="cb186-22"><a href="crosstalk.html#cb186-22"></a>  <span class="co"># create widget</span></span>
<span id="cb186-23"><a href="crosstalk.html#cb186-23"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb186-24"><a href="crosstalk.html#cb186-24"></a>    <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb186-25"><a href="crosstalk.html#cb186-25"></a>    x,</span>
<span id="cb186-26"><a href="crosstalk.html#cb186-26"></a>    <span class="dt">width =</span> width,</span>
<span id="cb186-27"><a href="crosstalk.html#cb186-27"></a>    <span class="dt">height =</span> height,</span>
<span id="cb186-28"><a href="crosstalk.html#cb186-28"></a>    <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb186-29"><a href="crosstalk.html#cb186-29"></a>    <span class="dt">elementId =</span> elementId,</span>
<span id="cb186-30"><a href="crosstalk.html#cb186-30"></a>    <span class="dt">sizingPolicy =</span> htmlwidgets<span class="op">::</span><span class="kw">sizingPolicy</span>(</span>
<span id="cb186-31"><a href="crosstalk.html#cb186-31"></a>      <span class="dt">padding =</span> <span class="dv">0</span>,</span>
<span id="cb186-32"><a href="crosstalk.html#cb186-32"></a>      <span class="dt">browser.fill =</span> <span class="ot">TRUE</span>,</span>
<span id="cb186-33"><a href="crosstalk.html#cb186-33"></a>      <span class="dt">defaultWidth =</span> <span class="st">&quot;100%&quot;</span></span>
<span id="cb186-34"><a href="crosstalk.html#cb186-34"></a>    ),</span>
<span id="cb186-35"><a href="crosstalk.html#cb186-35"></a>    <span class="dt">preRenderHook =</span> render_gio,</span>
<span id="cb186-36"><a href="crosstalk.html#cb186-36"></a>    <span class="co"># add crosstalk dependency</span></span>
<span id="cb186-37"><a href="crosstalk.html#cb186-37"></a>    <span class="dt">dependencies =</span> crosstalk<span class="op">::</span><span class="kw">crosstalkLibs</span>()</span>
<span id="cb186-38"><a href="crosstalk.html#cb186-38"></a>  )</span>
<span id="cb186-39"><a href="crosstalk.html#cb186-39"></a>}</span></code></pre></div>
<p>The widget will now ship with the crosstalk dependencies and the group name will be serialised and accessible in JavaScript.</p>
</div>
<div id="change-the-javascript-code" class="section level2" number="9.6">
<h2><span class="header-section-number">9.6</span> Change the JavaScript code</h2>
<p>What is left to do is to adapt the JavaScript code, as mentioned previously it must accept the keys selected in other widgets and share the selected key with other widgets.</p>
<p>First we create the selection handler in the <code>factory</code> function, this is done by instantiating a new class from <code>crosstalk.SelectionHandle</code>.</p>
<div class="sourceCode" id="cb187"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb187-1"><a href="crosstalk.html#cb187-1"></a><span class="kw">var</span> sel_handle <span class="op">=</span> <span class="kw">new</span> crosstalk<span class="op">.</span><span class="fu">SelectionHandle</span>()<span class="op">;</span></span></code></pre></div>
<p>Once the selection handle created it can be used in the <code>renderValue</code> function to define set the group.</p>
<div class="sourceCode" id="cb188"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb188-1"><a href="crosstalk.html#cb188-1"></a>sel_handle<span class="op">.</span><span class="fu">setGroup</span>(x<span class="op">.</span><span class="at">crosstalk</span><span class="op">.</span><span class="at">group</span>)<span class="op">;</span></span></code></pre></div>
<div id="send-selected-keys" class="section level3" number="9.6.1">
<h3><span class="header-section-number">9.6.1</span> Send selected keys</h3>
<p>In order to send the selected keys to crosstalk we shall need to use the one callback function that gio allows using. This callback function is fired every time a user selects a country on the globe and accepts two arguments, one containing data on the country selected and another containing data on the related countries (the arcs coming and leaving the selected country). For this exercise only the selected country is of use. The callback function that one wants to have run every time a country is picked by the user can be passed to <code>controller.onCountryPicked</code></p>
<p>Let us first explore the what is within the object <code>selectedCountry</code> object by logging it to the console.</p>
<div class="sourceCode" id="cb189"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb189-1"><a href="crosstalk.html#cb189-1"></a><span class="co">// placed in renderValue function</span></span>
<span id="cb189-2"><a href="crosstalk.html#cb189-2"></a></span>
<span id="cb189-3"><a href="crosstalk.html#cb189-3"></a><span class="co">// create callback function</span></span>
<span id="cb189-4"><a href="crosstalk.html#cb189-4"></a><span class="kw">function</span> <span class="fu">callback</span> (selectedCountry) {</span>
<span id="cb189-5"><a href="crosstalk.html#cb189-5"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(selectedCountry)<span class="op">;</span></span>
<span id="cb189-6"><a href="crosstalk.html#cb189-6"></a>}</span>
<span id="cb189-7"><a href="crosstalk.html#cb189-7"></a></span>
<span id="cb189-8"><a href="crosstalk.html#cb189-8"></a><span class="co">// pass it to gio.js</span></span>
<span id="cb189-9"><a href="crosstalk.html#cb189-9"></a>controller<span class="op">.</span><span class="fu">onCountryPicked</span>(callback)<span class="op">;</span></span></code></pre></div>
<div class="sourceCode" id="cb190"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb190-1"><a href="crosstalk.html#cb190-1"></a><span class="fu">{</span><span class="er">name</span><span class="fu">:</span> <span class="st">&quot;LIBYA&quot;</span><span class="fu">,</span> <span class="er">lat</span><span class="fu">:</span> <span class="dv">25</span><span class="fu">,</span> <span class="er">lon</span><span class="fu">:</span> <span class="dv">17</span><span class="fu">,</span> <span class="er">center</span><span class="fu">:</span> <span class="er">n</span><span class="fu">,</span> <span class="er">ISOCode</span><span class="fu">:</span> <span class="st">&quot;LY&quot;</span><span class="fu">}</span></span></code></pre></div>
<p>As mentioned at the beginning of this section, the keys used with the datasets for gio.js should be ISO codes, therefore one can consider the <code>ISOCode</code> variable as selected <code>key</code>. The <code>set</code> method from the selection handle can be used to share the selected key with other widgets. Note that this method expects either a <code>null</code> value or an array a scalar value will throw an error, hence <code>selectedCountry.ISOCode</code> is wrapped in square brackets.</p>
<div class="sourceCode" id="cb191"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb191-1"><a href="crosstalk.html#cb191-1"></a><span class="kw">function</span> <span class="fu">callback</span> (selectedCountry) {</span>
<span id="cb191-2"><a href="crosstalk.html#cb191-2"></a>  sel_handle<span class="op">.</span><span class="fu">set</span>([selectedCountry<span class="op">.</span><span class="at">ISOCode</span>])<span class="op">;</span></span>
<span id="cb191-3"><a href="crosstalk.html#cb191-3"></a>}</span>
<span id="cb191-4"><a href="crosstalk.html#cb191-4"></a></span>
<span id="cb191-5"><a href="crosstalk.html#cb191-5"></a>controller<span class="op">.</span><span class="fu">onCountryPicked</span>(callback)<span class="op">;</span></span></code></pre></div>
</div>
<div id="set-selected-keys" class="section level3" number="9.6.2">
<h3><span class="header-section-number">9.6.2</span> Set selected keys</h3>
<p>We have implemented the necessary to share the selected country with other widgets but are yet to implemented the opposite; when users select a country in another widget the selected country in gio should change too.</p>
<div class="sourceCode" id="cb192"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb192-1"><a href="crosstalk.html#cb192-1"></a><span class="co">// placed in factory function</span></span>
<span id="cb192-2"><a href="crosstalk.html#cb192-2"></a>sel_handle<span class="op">.</span><span class="fu">on</span>(<span class="st">&quot;change&quot;</span><span class="op">,</span> <span class="kw">function</span>(e) {</span>
<span id="cb192-3"><a href="crosstalk.html#cb192-3"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(e)<span class="op">;</span></span>
<span id="cb192-4"><a href="crosstalk.html#cb192-4"></a>})<span class="op">;</span></span></code></pre></div>
<div class="sourceCode" id="cb193"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb193-1"><a href="crosstalk.html#cb193-1"></a><span class="fu">{</span></span>
<span id="cb193-2"><a href="crosstalk.html#cb193-2"></a>  <span class="er">oldValue</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
<span id="cb193-3"><a href="crosstalk.html#cb193-3"></a>  <span class="er">sender</span><span class="fu">:</span> <span class="er">n</span> <span class="fu">{</span></span>
<span id="cb193-4"><a href="crosstalk.html#cb193-4"></a>    <span class="er">_eventRelay</span><span class="fu">:</span> <span class="er">e</span><span class="fu">,</span> </span>
<span id="cb193-5"><a href="crosstalk.html#cb193-5"></a>    <span class="er">_emitter</span><span class="fu">:</span> <span class="er">t</span><span class="fu">,</span> </span>
<span id="cb193-6"><a href="crosstalk.html#cb193-6"></a>    <span class="er">_group</span><span class="fu">:</span> <span class="st">&quot;SharedDatac7682f87&quot;</span><span class="fu">,</span> </span>
<span id="cb193-7"><a href="crosstalk.html#cb193-7"></a>    <span class="er">_var</span><span class="fu">:</span> <span class="er">r</span><span class="fu">,</span> </span>
<span id="cb193-8"><a href="crosstalk.html#cb193-8"></a>    <span class="er">_varOnChangeSub</span><span class="fu">:</span> <span class="st">&quot;sub1&quot;</span><span class="fu">,</span> </span>
<span id="cb193-9"><a href="crosstalk.html#cb193-9"></a>    <span class="er">…</span></span>
<span id="cb193-10"><a href="crosstalk.html#cb193-10"></a>  <span class="fu">},</span></span>
<span id="cb193-11"><a href="crosstalk.html#cb193-11"></a>  <span class="er">value</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;AE&quot;</span><span class="ot">]</span></span>
<span id="cb193-12"><a href="crosstalk.html#cb193-12"></a><span class="fu">}</span></span></code></pre></div>
<ol style="list-style-type: decimal">
<li><code>oldValue</code> - the value that was previously selected (if any), this may be useful if the widget wants to calculate differences between the currently and previously selected value.</li>
<li><code>sender</code> - the selection handle instance that made the change. This is useful to compare against the selection handle of the widget and know whether the change in selection was initiated by this widget or another. It is often used to clear the selection or filtering before applying a new one when the change comes from another widget.</li>
<li><code>value</code> - the array of selected keys.</li>
</ol>
<p>Therefore the listening to the change event on the selection would look like this. Note that 1) the selection cannot be cleared with gio.js, a country is always selected, and 2) one can only select one country a time, hence only accepting the first element of the selected keys with <code>e.value[0]</code>.</p>
<div class="sourceCode" id="cb194"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb194-1"><a href="crosstalk.html#cb194-1"></a><span class="co">// placed in factory function</span></span>
<span id="cb194-2"><a href="crosstalk.html#cb194-2"></a>sel_handle<span class="op">.</span><span class="fu">on</span>(<span class="st">&quot;change&quot;</span><span class="op">,</span> <span class="kw">function</span>(e) {</span>
<span id="cb194-3"><a href="crosstalk.html#cb194-3"></a>  <span class="cf">if</span> (e<span class="op">.</span><span class="at">sender</span> <span class="op">!==</span> sel_handle) {</span>
<span id="cb194-4"><a href="crosstalk.html#cb194-4"></a>    <span class="co">// clear the selection</span></span>
<span id="cb194-5"><a href="crosstalk.html#cb194-5"></a>    <span class="co">// not possible with gio.js</span></span>
<span id="cb194-6"><a href="crosstalk.html#cb194-6"></a>  }</span>
<span id="cb194-7"><a href="crosstalk.html#cb194-7"></a>  controller<span class="op">.</span><span class="fu">switchCountry</span>(e<span class="op">.</span><span class="at">value</span>[<span class="dv">0</span>])<span class="op">;</span></span>
<span id="cb194-8"><a href="crosstalk.html#cb194-8"></a>})<span class="op">;</span></span></code></pre></div>
<p>To recap, this is what the JavaScript code should not look like.</p>
<div class="sourceCode" id="cb195"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb195-1"><a href="crosstalk.html#cb195-1"></a>HTMLWidgets<span class="op">.</span><span class="fu">widget</span>({</span>
<span id="cb195-2"><a href="crosstalk.html#cb195-2"></a></span>
<span id="cb195-3"><a href="crosstalk.html#cb195-3"></a>  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;gio&#39;</span><span class="op">,</span></span>
<span id="cb195-4"><a href="crosstalk.html#cb195-4"></a></span>
<span id="cb195-5"><a href="crosstalk.html#cb195-5"></a>  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></span>
<span id="cb195-6"><a href="crosstalk.html#cb195-6"></a></span>
<span id="cb195-7"><a href="crosstalk.html#cb195-7"></a>  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) {</span>
<span id="cb195-8"><a href="crosstalk.html#cb195-8"></a></span>
<span id="cb195-9"><a href="crosstalk.html#cb195-9"></a>    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></span>
<span id="cb195-10"><a href="crosstalk.html#cb195-10"></a>    <span class="kw">var</span> controller<span class="op">;</span></span>
<span id="cb195-11"><a href="crosstalk.html#cb195-11"></a></span>
<span id="cb195-12"><a href="crosstalk.html#cb195-12"></a>    <span class="co">// create selection handle</span></span>
<span id="cb195-13"><a href="crosstalk.html#cb195-13"></a>    <span class="kw">var</span> sel_handle <span class="op">=</span> <span class="kw">new</span> crosstalk<span class="op">.</span><span class="fu">SelectionHandle</span>()<span class="op">;</span></span>
<span id="cb195-14"><a href="crosstalk.html#cb195-14"></a></span>
<span id="cb195-15"><a href="crosstalk.html#cb195-15"></a>    <span class="co">// listen to change</span></span>
<span id="cb195-16"><a href="crosstalk.html#cb195-16"></a>    sel_handle<span class="op">.</span><span class="fu">on</span>(<span class="st">&quot;change&quot;</span><span class="op">,</span> <span class="kw">function</span>(e) {</span>
<span id="cb195-17"><a href="crosstalk.html#cb195-17"></a>      <span class="cf">if</span> (e<span class="op">.</span><span class="at">sender</span> <span class="op">!==</span> sel_handle) {</span>
<span id="cb195-18"><a href="crosstalk.html#cb195-18"></a>        <span class="co">// clear selection</span></span>
<span id="cb195-19"><a href="crosstalk.html#cb195-19"></a>      }</span>
<span id="cb195-20"><a href="crosstalk.html#cb195-20"></a>      controller<span class="op">.</span><span class="fu">switchCountry</span>(e<span class="op">.</span><span class="at">value</span>[<span class="dv">0</span>])<span class="op">;</span></span>
<span id="cb195-21"><a href="crosstalk.html#cb195-21"></a>    })<span class="op">;</span></span>
<span id="cb195-22"><a href="crosstalk.html#cb195-22"></a></span>
<span id="cb195-23"><a href="crosstalk.html#cb195-23"></a></span>
<span id="cb195-24"><a href="crosstalk.html#cb195-24"></a>    <span class="cf">return</span> {</span>
<span id="cb195-25"><a href="crosstalk.html#cb195-25"></a></span>
<span id="cb195-26"><a href="crosstalk.html#cb195-26"></a>      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) {</span>
<span id="cb195-27"><a href="crosstalk.html#cb195-27"></a></span>
<span id="cb195-28"><a href="crosstalk.html#cb195-28"></a>        controller <span class="op">=</span> <span class="kw">new</span> GIO<span class="op">.</span><span class="fu">Controller</span>(el)<span class="op">;</span></span>
<span id="cb195-29"><a href="crosstalk.html#cb195-29"></a></span>
<span id="cb195-30"><a href="crosstalk.html#cb195-30"></a>        <span class="co">// group</span></span>
<span id="cb195-31"><a href="crosstalk.html#cb195-31"></a>        sel_handle<span class="op">.</span><span class="fu">setGroup</span>(x<span class="op">.</span><span class="at">crosstalk</span><span class="op">.</span><span class="at">group</span>)<span class="op">;</span></span>
<span id="cb195-32"><a href="crosstalk.html#cb195-32"></a>        </span>
<span id="cb195-33"><a href="crosstalk.html#cb195-33"></a>        <span class="co">// add data</span></span>
<span id="cb195-34"><a href="crosstalk.html#cb195-34"></a>        controller<span class="op">.</span><span class="fu">addData</span>(x<span class="op">.</span><span class="at">data</span>)<span class="op">;</span></span>
<span id="cb195-35"><a href="crosstalk.html#cb195-35"></a></span>
<span id="cb195-36"><a href="crosstalk.html#cb195-36"></a>        controller<span class="op">.</span><span class="fu">setStyle</span>(x<span class="op">.</span><span class="at">style</span>)<span class="op">;</span></span>
<span id="cb195-37"><a href="crosstalk.html#cb195-37"></a></span>
<span id="cb195-38"><a href="crosstalk.html#cb195-38"></a>        <span class="co">// callback</span></span>
<span id="cb195-39"><a href="crosstalk.html#cb195-39"></a>        <span class="kw">function</span> callback (selectedCountry<span class="op">,</span> relatedCountries) {</span>
<span id="cb195-40"><a href="crosstalk.html#cb195-40"></a>          sel_handle<span class="op">.</span><span class="fu">set</span>([selectedCountry<span class="op">.</span><span class="at">ISOCode</span>])<span class="op">;</span> <span class="co">// send keys</span></span>
<span id="cb195-41"><a href="crosstalk.html#cb195-41"></a>        }</span>
<span id="cb195-42"><a href="crosstalk.html#cb195-42"></a></span>
<span id="cb195-43"><a href="crosstalk.html#cb195-43"></a>        controller<span class="op">.</span><span class="fu">onCountryPicked</span>(callback)<span class="op">;</span></span>
<span id="cb195-44"><a href="crosstalk.html#cb195-44"></a></span>
<span id="cb195-45"><a href="crosstalk.html#cb195-45"></a>        <span class="co">// use stats</span></span>
<span id="cb195-46"><a href="crosstalk.html#cb195-46"></a>        <span class="cf">if</span>(x<span class="op">.</span><span class="at">stats</span>)</span>
<span id="cb195-47"><a href="crosstalk.html#cb195-47"></a>          controller<span class="op">.</span><span class="fu">enableStats</span>()<span class="op">;</span></span>
<span id="cb195-48"><a href="crosstalk.html#cb195-48"></a></span>
<span id="cb195-49"><a href="crosstalk.html#cb195-49"></a>        <span class="co">// render</span></span>
<span id="cb195-50"><a href="crosstalk.html#cb195-50"></a>        controller<span class="op">.</span><span class="fu">init</span>()<span class="op">;</span></span>
<span id="cb195-51"><a href="crosstalk.html#cb195-51"></a></span>
<span id="cb195-52"><a href="crosstalk.html#cb195-52"></a>      }<span class="op">,</span></span>
<span id="cb195-53"><a href="crosstalk.html#cb195-53"></a></span>
<span id="cb195-54"><a href="crosstalk.html#cb195-54"></a>      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) {</span>
<span id="cb195-55"><a href="crosstalk.html#cb195-55"></a>        controller<span class="op">.</span><span class="fu">resizeUpdate</span>()<span class="op">;</span></span>
<span id="cb195-56"><a href="crosstalk.html#cb195-56"></a>      }<span class="op">,</span></span>
<span id="cb195-57"><a href="crosstalk.html#cb195-57"></a></span>
<span id="cb195-58"><a href="crosstalk.html#cb195-58"></a>    }<span class="op">;</span></span>
<span id="cb195-59"><a href="crosstalk.html#cb195-59"></a>  }</span>
<span id="cb195-60"><a href="crosstalk.html#cb195-60"></a>})<span class="op">;</span></span></code></pre></div>
</div>
<div id="using-crosstalk-with-gio" class="section level3" number="9.6.3">
<h3><span class="header-section-number">9.6.3</span> Using crosstalk with gio</h3>
<p>Finally, now that gio supports we can create a few examples to demonstrate how it can be used.</p>
<p>The simplest way is probably to convert the edges to a shared dataset specifying either the source (<code>i</code>) or target (<code>e</code>) country codes as keys. However this is unlikely to be used this way out in the real world. In the example below selecting an edge highlights a node which is somewhat confusing.</p>
<div class="sourceCode" id="cb196"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb196-1"><a href="crosstalk.html#cb196-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb196-2"><a href="crosstalk.html#cb196-2"></a><span class="kw">library</span>(gio)</span>
<span id="cb196-3"><a href="crosstalk.html#cb196-3"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb196-4"><a href="crosstalk.html#cb196-4"></a></span>
<span id="cb196-5"><a href="crosstalk.html#cb196-5"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb196-6"><a href="crosstalk.html#cb196-6"></a>  <span class="st">&quot;https://raw.githubusercontent.com/JohnCoene/&quot;</span>,</span>
<span id="cb196-7"><a href="crosstalk.html#cb196-7"></a>  <span class="st">&quot;javascript-for-r/master/data/countries.json&quot;</span></span>
<span id="cb196-8"><a href="crosstalk.html#cb196-8"></a>)</span>
<span id="cb196-9"><a href="crosstalk.html#cb196-9"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(url)</span>
<span id="cb196-10"><a href="crosstalk.html#cb196-10"></a></span>
<span id="cb196-11"><a href="crosstalk.html#cb196-11"></a><span class="co"># Wrap data frame in SharedData</span></span>
<span id="cb196-12"><a href="crosstalk.html#cb196-12"></a><span class="co"># key is importing country</span></span>
<span id="cb196-13"><a href="crosstalk.html#cb196-13"></a>sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(arcs, <span class="dt">key =</span> arcs<span class="op">$</span>i)</span>
<span id="cb196-14"><a href="crosstalk.html#cb196-14"></a></span>
<span id="cb196-15"><a href="crosstalk.html#cb196-15"></a><span class="kw">bscols</span>(</span>
<span id="cb196-16"><a href="crosstalk.html#cb196-16"></a>  <span class="kw">gio</span>(sd),</span>
<span id="cb196-17"><a href="crosstalk.html#cb196-17"></a>  <span class="kw">datatable</span>(sd, <span class="dt">width=</span><span class="st">&quot;100%&quot;</span>, <span class="dt">selection =</span> <span class="st">&quot;single&quot;</span>)</span>
<span id="cb196-18"><a href="crosstalk.html#cb196-18"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/crosstalk-gio-1.png" alt="" />
<p class="caption">Gio with DT using crosstalk</p>
</div>
<p>Thankfully we can use the <code>group</code> argument in order to create edges and nodes that share keys and produce a more sensible linkage. Below we create two shared datasets with the same group name, one for the edges and another for the nodes and use one for the gio visualisation and the other for the plotly graph.</p>
<div class="sourceCode" id="cb197"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb197-1"><a href="crosstalk.html#cb197-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb197-2"><a href="crosstalk.html#cb197-2"></a><span class="kw">library</span>(plotly)</span>
<span id="cb197-3"><a href="crosstalk.html#cb197-3"></a><span class="kw">library</span>(crosstalk)</span>
<span id="cb197-4"><a href="crosstalk.html#cb197-4"></a></span>
<span id="cb197-5"><a href="crosstalk.html#cb197-5"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb197-6"><a href="crosstalk.html#cb197-6"></a>  <span class="st">&quot;https://raw.githubusercontent.com/JohnCoene/&quot;</span>,</span>
<span id="cb197-7"><a href="crosstalk.html#cb197-7"></a>  <span class="st">&quot;javascript-for-r/master/data/countries.json&quot;</span></span>
<span id="cb197-8"><a href="crosstalk.html#cb197-8"></a>)</span>
<span id="cb197-9"><a href="crosstalk.html#cb197-9"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(url)</span>
<span id="cb197-10"><a href="crosstalk.html#cb197-10"></a></span>
<span id="cb197-11"><a href="crosstalk.html#cb197-11"></a><span class="co"># Wrap data frame in SharedData</span></span>
<span id="cb197-12"><a href="crosstalk.html#cb197-12"></a>edges_sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(arcs, <span class="dt">key =</span> arcs<span class="op">$</span>i, <span class="dt">group =</span> <span class="st">&quot;gio&quot;</span>)</span>
<span id="cb197-13"><a href="crosstalk.html#cb197-13"></a></span>
<span id="cb197-14"><a href="crosstalk.html#cb197-14"></a><span class="co"># create nodes</span></span>
<span id="cb197-15"><a href="crosstalk.html#cb197-15"></a>iso2c &lt;-<span class="st"> </span><span class="kw">unique</span>(arcs<span class="op">$</span>i)</span>
<span id="cb197-16"><a href="crosstalk.html#cb197-16"></a>nodes &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb197-17"><a href="crosstalk.html#cb197-17"></a>  <span class="dt">country =</span> iso2c,</span>
<span id="cb197-18"><a href="crosstalk.html#cb197-18"></a>  <span class="dt">y =</span> <span class="kw">rnorm</span>(<span class="kw">length</span>(iso2c))</span>
<span id="cb197-19"><a href="crosstalk.html#cb197-19"></a>)</span>
<span id="cb197-20"><a href="crosstalk.html#cb197-20"></a>nodes_sd &lt;-<span class="st"> </span>SharedData<span class="op">$</span><span class="kw">new</span>(</span>
<span id="cb197-21"><a href="crosstalk.html#cb197-21"></a>  nodes, <span class="dt">key =</span> nodes<span class="op">$</span>country, </span>
<span id="cb197-22"><a href="crosstalk.html#cb197-22"></a>  <span class="dt">group =</span> <span class="st">&quot;gio&quot;</span></span>
<span id="cb197-23"><a href="crosstalk.html#cb197-23"></a>)</span>
<span id="cb197-24"><a href="crosstalk.html#cb197-24"></a></span>
<span id="cb197-25"><a href="crosstalk.html#cb197-25"></a><span class="kw">bscols</span>(</span>
<span id="cb197-26"><a href="crosstalk.html#cb197-26"></a>  <span class="kw">plot_ly</span>(<span class="dt">data =</span> nodes_sd, <span class="dt">type =</span> <span class="st">&quot;bar&quot;</span>, <span class="dt">x =</span> <span class="op">~</span>country, <span class="dt">y =</span> <span class="op">~</span>y) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb197-27"><a href="crosstalk.html#cb197-27"></a><span class="st">    </span><span class="kw">config</span>(<span class="dt">displayModeBar =</span> <span class="ot">FALSE</span>),</span>
<span id="cb197-28"><a href="crosstalk.html#cb197-28"></a>  <span class="kw">gio</span>(edges_sd)</span>
<span id="cb197-29"><a href="crosstalk.html#cb197-29"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/crosstalk-gio-2.png" alt="" />
<p class="caption">Gio with DT and plotly using crosstalk</p>
</div>

</div>
</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-crosstalk">
<p>Cheng, Joe. 2020. <em>Crosstalk: Inter-Widget Interactivity for Html Widgets</em>. <a href="https://CRAN.R-project.org/package=crosstalk">https://CRAN.R-project.org/package=crosstalk</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="advanced-topics.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="final-revisions.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/3-26-htmlwidgets-crosstalk.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
